package com.ai.vita.redis.client;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * redisUtil.
 */
public class RedisUtil {

    private Map<String, JedisPool> pools = new HashMap();

    private Map<String, Long> clientTimes = new HashMap();

    private long timeliness;

    private JedisPoolConfig config;

    private int timeout;

    public void setTimeliness(long timeliness) {
        this.timeliness = timeliness;
    }

    public void setConfig(JedisPoolConfig config) {
        this.config = config;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
     * 从clientName得到serverName.
     * @param clientName
     * @return
     */
    private String getServerName(String clientName){
        return clientName.split("/")[1];
    }

    /**
     * 校验客户端有效性.
     * @param clientName
     * @return
     */
    public boolean validate(String clientName){
        Long preTime = clientTimes.get(clientName);
        Long curTime = new Date().getTime();
        if(preTime == null || curTime - preTime > timeliness){
            throw new RuntimeException("已失效，请重新连接...");
        }else {
            return true;
        }
    }

    /**
     * 客户端连接初始化.
     * @param token
     * @param host
     * @param port
     * @param password
     * @return
     */
    public String init(String token, String host, int port, String password){
        String serverName = host + ":" + port;
        String clientName = token + "/" + serverName;
        Long curTime = new Date().getTime();
        JedisPool pool = pools.get(serverName);
        //验证合法性
        Jedis jedis = create(host, port, password);
        if(jedis != null){
            //合法
            if(pool == null){
                //不存在连接池，创建
                pool = createPool(host, port, password);
                pools.put(serverName, pool);
            }
            clientTimes.put(clientName, curTime);
        }else {
            //不合法
            throw new RuntimeException("连接验证失败");
        }
        return clientName;
    }

    /**
     * 创建连接.
     * @param host
     * @param port
     * @param password
     * @return
     */
    public Jedis create(String host, int port, String password){
        try {
            Jedis jedis = new Jedis(host, port, timeout);
            if(password != null && !"".equals(password)){
                jedis.auth(password);
            }
            return jedis;
        }catch (RuntimeException e){
            return null;
        }
    }

    /**
     * 创建连接池.
     * @param host
     * @param port
     * @param password
     * @return
     */
    public JedisPool createPool(String host, int port, String password){
        try {
            JedisPool pool;
            if(password != null && !"".equals(password)){
                pool = new JedisPool(this.config, host, port, timeout, password);
            }else {
                pool = new JedisPool(this.config, host, port, timeout);
            }
            return pool;
        }catch (RuntimeException e){
            return null;
        }
    }

    /**
     * 关闭连接.
     * @param jedis
     */
    public void close(Jedis jedis){
        if(jedis != null){
            jedis.close();
        }
    }

    /**
     * 关闭连接池.
     * @param jedisPool
     */
    public void closePool(JedisPool jedisPool){
        if(jedisPool != null){
            jedisPool.close();
        }
    }

    /**
     * 根据clientName获取客户端.
     * @param clientName
     * @return
     */
    public Jedis get(String clientName){
        if(validate(clientName)){
            String serverName = getServerName(clientName);
            JedisPool pool = pools.get(serverName);
            if(pool != null){
                return pool.getResource();
            }else {
                return null;
            }
        }else {
            throw new RuntimeException("连接已超时，请重新连接...");
        }
    }

}
